using System;
using System.Collections;
using System.IO;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace stsdev
{

    public class SolutionConfigBuilder
    {

        #region "Create method overloads with optional parameter support"
        public static void Create(string FilePath)
        {
            Create(FilePath, true);
        }

        public static void Create(string FilePath, bool AssemblyDeployment)
        {
            Create(FilePath,
                   AssemblyDeployment,
                   false);
        }

        public static void Create(string FilePath, bool AssemblyDeployment, bool SafeControlSettings)
        {
            Create(FilePath,
                   AssemblyDeployment,
                   SafeControlSettings,
                   AssemblyDeploymentTarget.GlobalAssemblyCache);
        }

        public static void Create(string FilePath, bool AssemblyDeployment, bool SafeControlSettings, AssemblyDeploymentTarget DeploymentTarget)
        {
            Create(FilePath,
                  AssemblyDeployment,
                  SafeControlSettings,
                  AssemblyDeploymentTarget.GlobalAssemblyCache,
                  null);
        }


        public static void Create(string FilePath, bool AssemblyDeployment, bool SafeControlSettings, AssemblyDeploymentTarget DeploymentTarget, PermissionSet CasPermissions)
        {
            Create(FilePath, AssemblyDeployment, SafeControlSettings, DeploymentTarget, CasPermissions, false);
        }
        #endregion

        public static void Create(string FilePath, bool AssemblyDeployment, bool SafeControlSettings, AssemblyDeploymentTarget DeploymentTarget, PermissionSet CasPermissions, bool DwpFiles)
        {
            StreamWriter manifestStream = new StreamWriter(FilePath);
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Encoding = Encoding.UTF8;
            settings.Indent = true;
            settings.NewLineOnAttributes = false;
            settings.NewLineHandling = NewLineHandling.None;
            XmlWriter writer = XmlWriter.Create(manifestStream, settings);
            writer.WriteStartDocument();

            writer.WriteComment("Created by STSDEV at " + DateTime.Now.ToString());
            writer.WriteStartElement("Solution");

            // create new guid and use it as solution ID
            writer.WriteStartElement("SolutionId");
            SolutionBuilder.SolutionId = Guid.NewGuid().ToString().ToUpper();
            writer.WriteValue(SolutionBuilder.SolutionId);
            writer.WriteEndElement();

            // add solution name
            writer.WriteStartElement("SolutionName");
            writer.WriteValue(SolutionBuilder.SolutionName);
            writer.WriteEndElement();

            // add value to track whether solution deployment/upgrade issues IISRESET
            writer.WriteStartElement("ResetWebServer");
            writer.WriteValue("True");
            writer.WriteEndElement();

            // add boolean to track whether solution needs assembly in deployment package
            writer.WriteStartElement("AssemblyDeployment");
            writer.WriteValue(AssemblyDeployment.ToString());
            writer.WriteEndElement();

            // add boolean to track whether solution needs assembly in deployment package
            writer.WriteStartElement("SafeControlSettings");
            writer.WriteValue(SafeControlSettings.ToString());
            writer.WriteEndElement();

            // add boolean to track whether solution needs assembly in deployment package
            writer.WriteStartElement("CasPermissions");
            writer.WriteValue((CasPermissions != null).ToString());
            writer.WriteEndElement();

            if (AssemblyDeployment)
            {
                // write Assembly Files
                writer.WriteComment("Assembly files");
                writer.WriteStartElement("Assemblies");
                writer.WriteStartElement("Assembly");
                writer.WriteAttributeString("Location", SolutionBuilder.TargetName + ".dll");
                writer.WriteAttributeString("DeploymentTarget", DeploymentTarget.ToString());
                writer.WriteStartElement("SafeControls");
                writer.WriteStartElement("SafeControl");
                writer.WriteAttributeString("Assembly", SolutionBuilder.FullAssemblyName);
                writer.WriteAttributeString("Namespace", SolutionBuilder.TargetName);
                writer.WriteAttributeString("TypeName", "*");
                writer.WriteAttributeString("Safe", "True");
                writer.WriteEndElement();
                writer.WriteEndElement();
                writer.WriteEndElement();
                writer.WriteEndElement();
            }

            if (CasPermissions != null)
            {
                writer.WriteStartElement("CodeAccessSecurity");
                writer.WriteStartElement("PolicyItem");
                writer.WriteStartElement("PermissionSet");
                writer.WriteAttributeString("class", "NamedPermissionSet");
                writer.WriteAttributeString("version", "1");
                writer.WriteAttributeString("Name", SolutionBuilder.TargetName);
                // write out each CAS permission as an IPermission element
                foreach (SecurityElement se in CasPermissions.ToXml().Children)
                {
                    writer.WriteStartElement("IPermission");
                    foreach (DictionaryEntry de in se.Attributes)
                    {
                        writer.WriteAttributeString(de.Key.ToString(), de.Value.ToString());
                    }
                    writer.WriteEndElement(); // </IPermission>
                }
                writer.WriteEndElement(); // </PermissionSet>
                writer.WriteStartElement("Assemblies");
                writer.WriteStartElement("Assembly");
                writer.WriteAttributeString("Name", SolutionBuilder.TargetName + ".dll");
                writer.WriteEndElement(); // </Assembly>
                writer.WriteEndElement(); // </Assemblies>
                writer.WriteEndElement(); // </PolicyItem>
                writer.WriteEndElement(); // </CodeAccessSecurity>  
            }

            //if (DwpFiles)
            //{
            //    //Add any webpart files that exist in the root file folder to the manifest.xml file
            //    writer.WriteStartElement("DwpFiles");
            //    foreach (string webpartfile in Directory.GetFiles(Globals.RootFilesFolder, "*.webpart"))
            //    {
            //        writer.WriteStartElement("DwpFile");
            //        writer.WriteAttributeString("FileName", webpartfile); // FileName="webpartfile.webpart"
            //        writer.WriteAttributeString("Location", webpartfile); // Location="webpartfile.webpart"
            //        writer.WriteEndElement(); // </DwpFile>
            //    }
            //    writer.WriteEndElement(); // </DwpFiles>
            //}
            writer.WriteEndElement(); // </Solution>
            writer.WriteEndDocument();
            writer.Close();
            manifestStream.Close();
        }
    }
}
